package yun.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class TrackIterator<E> {
	Random random = new Random();
	int index;
	List<E> list;
	List<E> originalList;
	boolean isRepeat;
	boolean isShuffle;

	public TrackIterator(int index, List<E> list, boolean repeat, boolean isShuffle) {
		this.originalList = new ArrayList<E>(list);
		this.list = new ArrayList<E>(list);
		this.index = index;
		setRepeat(repeat);
		setShuffle(isShuffle);
	}

	public void setRepeat(boolean isRepeat) {
		this.isRepeat = isRepeat;
	}

	public boolean isRepeat() {
		return isRepeat;
	}

	public void setShuffle(boolean isShuffle) {
		this.isShuffle = isShuffle;
		if (isShuffle) {
			newShuffleList();
		} else {
			newSequenceList(originalList);
		}
	}

	public boolean isShuffle() {
		return isShuffle;
	}

	public boolean hasCurrent() {
		if (index < 0) {
			return false;
		}
		if (index >= list.size()) {
			return false;
		}

		return true;
	}

	public E current() {
		return list.get(index);
	}

	public boolean hasNext() {
		int next = index + 1;
		if (next < list.size()) {
			return true;
		} else {
			return isRepeat();
		}
	}

	public E next() {
		index++;
		if (isRepeat() && index >= list.size()) {
			index = 0;
		}
		return current();
	}

	public boolean hasPrevious() {
		int previous = index - 1;
		if (previous >= 0) {
			return true;
		} else {
			return isRepeat();
		}
	}

	public E previous() {
		index--;
		if (isRepeat() && index < 0) {
			index = list.size() - 1;
		}
		return current();
	}

	private void newSequenceList(List<E> list) {
		E e = this.list.get(index);
		int len = originalList.size();
		E other;
		for (int i = 0; i < len; i++) {
			other = originalList.get(i);
			if (e.equals(other)) {
				index = i;
				break;
			}
		}

		this.list = new ArrayList<E>(list);
	}

	private void newShuffleList() {

		int randomIndex;
		E e;

		List<E> oldList = new ArrayList<E>(this.originalList);
		List<E> newList = new ArrayList<E>();

		//
		randomIndex = index;
		e = oldList.remove(randomIndex);
		newList.add(e);

		//
		while (oldList.size() > 0) {
			randomIndex = random.nextInt(oldList.size());
			e = oldList.remove(randomIndex);
			newList.add(e);
		}
		newSequenceList(newList);
		index = 0;
	}

}
